<template>
    <div>
<!--        ranges：{{ranges}}-->
        <el-form label-position="top" label-width="100" size="mini">

            <el-form-item align="center" style="padding-right:10px;">
                <table  class="sudo_table">
                    <tr v-for="(row, rowIndex) in data" :key="rowIndex"  :class="{'sudo_plan_border': true, 'sudo_bold_top_border': [0, 3, 6].includes(rowIndex), 'sudo_bold_bottom_border': [8].includes(rowIndex)}">
                        <td v-for="(column, columnIndex) in row" :key="columnIndex" :class="{'sudo_plan_border': true, 'sudo_bold_left_border': [0, 3, 6].includes(columnIndex)}">
                            <input :class="{'sudo_input': true}" size="2" autocomplete="off" maxlength="1" v-model="row[columnIndex]" onfocus="this.select()" >
                        </td>
                    </tr>
                </table>
            </el-form-item>
            <el-form-item label="包含失败尝试：">
                <el-switch
                        v-model="includeFailTry"
                        active-color="#13ce66"
                        inactive-color="#ff4949">
                </el-switch>
            </el-form-item>
            <el-form-item align="center" label-width="0" >
                <el-button size="mini" type="primary" @click="clearData" >清空</el-button>
                <el-button size="mini" type="primary" @click="toLoadData" >加载数据</el-button>
                <el-button size="mini" type="primary" @click="toDownload">下载原始数据</el-button>
                <el-button size="mini" type="primary" @click="calc" :loading="loading">计算</el-button>
                <el-button size="mini" v-show="!error && steps.length > 0 && currentStepIndex >= 0" type="primary" @click="prev">上一步</el-button>
                <el-button size="mini" v-show="!error && steps.length > 0 && currentStepIndex <= steps.length - 1" type="primary" @click="next">下一步</el-button>
            </el-form-item>
            <div v-if="error" v-loading="loading">
                <el-alert
                          title="无法计算，请检查数据是否有重复"
                          type="error"
                          effect="dark">
                </el-alert>
            </div>
            <div v-if="!error" v-loading="loading">
                <el-form-item label="" style="padding-right:10px;" v-if="currentStep" >
                    <span slot="label">第{{currentStepIndex+1}}步</span>
                    <span v-if="currentStep">
                        第{{currentStep.row+1}}行，第{{currentStep.column+1}}列，值为：{{currentStep.value}}，备注：{{currentStep.memo}}
                        <span style="color:red;">{{currentStep.effective ? '' : '，非有效尝试批次'}}</span>
                    </span>
                </el-form-item>
                <el-row v-if="steps.length > 0" >
                    <el-col :xs="24" :sm="12">
                        <el-form-item label="最终结果" style="padding-right:10px;" align="center" >
                            <table  class="sudo_table">
                                <tr v-for="(row, rowIndex) in finalData" :key="rowIndex"  :class="{'sudo_plan_border': true, 'sudo_bold_top_border': [0, 3, 6].includes(rowIndex), 'sudo_bold_bottom_border': [8].includes(rowIndex)}">
                                    <td v-for="(column, columnIndex) in row" :key="columnIndex" :class="{'sudo_plan_border': true, 'sudo_bold_left_border': [0, 3, 6].includes(columnIndex),'sudo_highlight_td': isHighLight(rowIndex, columnIndex)}">
                                        <span :class="{'sudo_concluded_td': isConcludedData(rowIndex, columnIndex)}">{{row[columnIndex]}}</span>
                                    </td>
                                </tr>
                            </table>
                            <el-row style="margin-top:5px;">
                                <el-button type="primary" @click="toDownloadCurrent">下载当前数据</el-button>
                            </el-row>
                        </el-form-item>
                        <div>
                            <span v-for="(range, rangeIndex) in ranges" :key="rangeIndex">
                                {{range.start+1}}-{{range.end+1}}：{{range.effective ? '有效' : '无效'}}{{rangeIndex == ranges.length -1 ? '。' : '；'}}
                            </span>
                        </div>
                    </el-col>
                    <el-col :xs="24" :sm="12">
                        <el-form-item label="步骤" style="padding-right:10px;" align="center">
                            <span slot="label">{{steps.length}}个步骤</span>
                            <el-table size="mini" ref="stepsTable"
                                      :data="steps"  @row-click="clickStepRow" :row-class-name="tableRowClassName" :cell-style="cellStyle"
                                      style="width: 100%" max-height="500" highlight-current-row>
                                <el-table-column label="步"
                                                 type="index"
                                                 width="50">
                                </el-table-column>
                                <el-table-column
                                        prop="level" width="50"
                                        label="级">
                                </el-table-column>
                                <el-table-column
                                        prop="row" width="50"
                                        label="行">
                                    <template slot-scope="scope">
                                        <span v-if="!scope.row.splitLine">{{scope.row.row + 1}}</span><span v-else>-</span>
                                    </template>
                                </el-table-column>
                                <el-table-column
                                        prop="column" width="50"
                                        label="列">
                                    <template slot-scope="scope">
                                        <span v-if="!scope.row.splitLine">{{scope.row.column + 1}}</span><span v-else>-</span>
                                    </template>
                                </el-table-column>
                                <el-table-column width="50"
                                                 prop="value"
                                                 label="值">
                                </el-table-column>
                                <el-table-column
                                        prop="memo"
                                        label="备注">
                                    <template slot-scope="scope">
                                        {{scope.row.memo}}<span v-if="!scope.row.splitLine" style="color:red;">{{scope.row.effective ? '' : '，非有效尝试批次'}}</span>
                                    </template>
                                </el-table-column>
                            </el-table>
                        </el-form-item>
                    </el-col>

                </el-row>
            </div>


        </el-form>

        <el-dialog
                title="数据"
                :visible.sync="dialogVisible"
                width="30%">
            <span>
                <el-input
                        type="textarea"
                        :autosize="{ minRows: 3, maxRows: 25}"
                        placeholder="请粘贴内容"
                        v-model="userInputData">
                </el-input>
            </span>
            <span slot="footer" class="dialog-footer">
            <el-button @click="dialogVisible = false">取 消</el-button>
            <el-button type="primary" @click="toApplySourceData">确 定</el-button>
          </span>
        </el-dialog>

    </div>
</template>

<script>
    /* eslint-disable */
    import FileSaver from 'file-saver'
    import axios from "axios";
    import lodash from 'lodash'
    export default {
        name: "sudo1",
        data() {
            return {
                loading: false,
                error: false,
                includeFailTry: true,
                data: [
                    [null, null, 5, 3, null, null, null, null, null],
                    [8, null, null, null, null, null, null, 2, null],
                    [null, 7, null, null, 1, null, 5, null, null],
                    [4, null, null, null, null, 5, 3, null, null],
                    [null, 1, null, null, 7, null, null, null, 6],
                    [null, null, 3, 2, null, null, null, 8, null],
                    [null, 6, null, 5, null, null, null, null, 9],
                    [null, null, 4, null, null, null, null, 3, null],
                    [null, null, null, null, null, 9, 7, null, null]
                ],
                finalData: [],
                steps: [],
                currentStep: null,
                currentStepIndex: -1,
                stepHistoryDataMap: {},
                ranges: [],
                dialogVisible: false,
                userInputData: '',
            }
        },
        methods: {
            toLoadData() {
                this.userInputData = ''
                this.dialogVisible = true
            },
            toApplySourceData() {
                let userInputData = null
                try {
                    userInputData = JSON.parse(this.userInputData)
                    this.data = userInputData
                    this.dialogVisible = false
                } catch (e) {
                    userInputData = null
                    this.$message.error('不是有效数据')
                }
            },
            toDownload() {
                let blob = new Blob([JSON.stringify(this.data,null,2)], {type: "text/plain;charset=utf-8"});
                let caseName = '数独数据'
                FileSaver.saveAs(blob, caseName + ".txt");
            },
            toDownloadCurrent() {
                let blob = new Blob([JSON.stringify(this.finalData,null,2)], {type: "text/plain;charset=utf-8"});
                let caseName = '数独数据-第' + (this.currentStepIndex + 1) + '步'
                FileSaver.saveAs(blob, caseName + ".txt");
            },
            clearData() {
              let data = lodash.cloneDeep(this.data)
              for (let i = 0; i < data.length; i++) {
                  for (let j = 0; j < data[i].length; j++) {
                      // console.log('data[i][j]:', data[i][j])
                      data[i][j] = null
                  }
              }
              this.data = data
            },
            cellStyle({row, cell, rowIndex}) {
                if (rowIndex > 0 && row.guess_id != this.steps[rowIndex-1].guess_id) {
                    return {'borderTop': '2px solid #1984c9'}
                }
                return {}
            },
            tableRowClassName ({row, rowIndex}) {
                //把每一行的索引放进row
                row.index = rowIndex;
            },
            isHighLight(rowIndex, columnIndex) {
              return this.currentStep && this.currentStep.row == rowIndex && this.currentStep.column == columnIndex
            },
            isConcludedData(rowIndex, columnIndex) {
              return !this.data[rowIndex][columnIndex]
            },
            async calc() {
                this.currentStepIndex = -1
                this.currentStep = null
                this.stepHistoryDataMap = {}
                this.ranges = []
                let postData = {
                    data: this.data,
                    include_fail_try: this.includeFailTry,
                }
                this.loading = true
                try {
                    let response = await axios.post('/process_sudo', postData)
                    // console.log('response:', response)
                    this.finalData = lodash.cloneDeep(this.data)
                    if (!response.data || Object.keys(response.data).length == 0) {
                        this.error = true
                    } else {
                        let steps = response.data.steps

                        if (steps && steps.length > 0) {
                            let currentRange = {start: 0, end: 0, effective: false}
                            for (let i = 0; i < steps.length - 1; i++) {
                                // console.log('i:', i)
                                let step = steps[i]
                                currentRange.effective = step.effective
                                if (step.effective != steps[i+1].effective) {
                                    currentRange.end = i
                                    this.ranges.push(currentRange)

                                    currentRange = {start: i + 1, end: 0, effective: false}
                                }
                            }

                            // 最后两步effective相等，则合并，否则则分开。
                            if (steps[steps.length - 1].effective == steps[steps.length - 2].effective) {
                                currentRange.end = steps.length - 1
                                this.ranges.push(currentRange)
                            } else {
                                currentRange.end = steps.length - 2
                                this.ranges.push(currentRange)

                                currentRange = {start: steps.length - 1, end: steps.length - 1, effective: steps[steps.length - 1].effective}
                                this.ranges.push(currentRange)
                            }
                        }

                        this.steps = steps
                        this.error = false
                    }

                } catch (e) {
                    this.error = true
                }
                this.loading = false
                this.$localStorage.set('sudo1.data', this.data, 4 * 60 * 60 * 1000) // keep 1 day
            },
            prev() {
                this.currentStepIndex--
                this.setCurrentStep()
            },
            next() {
                this.currentStepIndex++
                this.setCurrentStep()
            },
            gotoStep(destStep) {
                // console.log('destStep:', destStep)
                if (destStep > this.currentStepIndex) {
                    do {
                        this.next()
                    } while (destStep > this.currentStepIndex)
                } else if (destStep < this.currentStepIndex) {
                    do {
                        this.prev()
                    } while (destStep < this.currentStepIndex)
                }
            },
            clickStepRow(row) {
                // console.log('row:', row)
                this.gotoStep(row.index)
            },
            setCurrentStep() {
                let currentStep = null
                if (this.currentStepIndex >= 0 && this.currentStepIndex <= this.steps.length - 1) {
                    currentStep = this.steps[this.currentStepIndex]
                    // console.log('currentStep:', currentStep)
                    // console.log('this.$refs.stepsTable:', this.$refs.stepsTable)
                    this.$refs.stepsTable.setCurrentRow(currentStep)
                }
                this.currentStep = currentStep

                if (this.currentStep) {
                    if (this.stepHistoryDataMap[this.currentStepIndex]) {
                        this.finalData = lodash.cloneDeep(this.stepHistoryDataMap[this.currentStepIndex])
                    } else {
                        this.finalData[this.currentStep.row][this.currentStep.column] = this.currentStep.value
                        this.stepHistoryDataMap[this.currentStepIndex] = lodash.cloneDeep(this.finalData)
                    }

                    if (this.currentStep.values && this.currentStep.values.length > 0) {
                        for (let i = 0; i < this.currentStep.values.length; i++) {
                            let row = this.currentStep.values[i]
                            for (let j = 0; j < row.length; j++) {
                                let tdValue = row[j]
                                // console.log('tdValue:', tdValue, typeof(tdValue) == "number")
                                if (typeof(tdValue) == "number") {
                                    this.finalData[i][j] = tdValue
                                } else {
                                    this.finalData[i][j] = null
                                }
                            }
                        }
                    }

                    this.updateScroll()
                }
            },
            updateScroll() {
                // let curIndex = 0;
                //
                // // 如果当前索引变化
                // if (curIndex !== this.currentStepIndex) {
                //     let vmEl = this.$refs.stepsTable.$el;
                //     if (vmEl) {
                //         // 计算滚动条的位置
                //         const targetTop = vmEl.querySelectorAll('.el-table__body tr')[curIndex].getBoundingClientRect().top
                //         const containerTop = vmEl.querySelector('.el-table__body').getBoundingClientRect().top
                //         console.log('targetTop:', targetTop, 'containerTop:', containerTop, 'scrollTop:', this.$refs.stepsTable.bodyWrapper.scrollTop)
                //         if (targetTop - containerTop - 500 > this.$refs.stepsTable.bodyWrapper.scrollTop ||
                //             curIndex < this.currentStepIndex) {
                //             this.$refs.stepsTable.bodyWrapper.scrollTop = targetTop - containerTop;
                //         }
                //     }
                // }
            },

        },
        mounted() {
            // let data = this.$localStorage.get('sudo1.data')
            // if (data) {
            //     this.data = data
            // }
            // this.calc()
        }
    }
</script>

<style scoped>
    .sudo_table {
        border-collapse: collapse;
        background-color: #FFFFFF;
        border-right: #666699 solid 2px;
    }
    .sudo_table td {
        width: 30pt;
        height: 30pt;
        vertical-align: middle;
        text-align: center;
        font-size: 24pt;
        font-family: times,serif;
    }
    .sudo_bold_left_border {
        border-left: #666699 solid 2px !important
    }
    .sudo_bold_top_border {
        border-top: #666699 solid 2px !important
    }
    .sudo_bold_bottom_border {
        border-bottom: #666699 solid 2px !important
    }
    .sudo_plan_border {
        border: #DDDDEE solid 1px
    }
    .sudo_input {
        -webkit-appearance: none;
        outline: none;
        border: solid 0 #fff;
        text-align: center;
        margin: 0;
        width: 24pt;
        font-size: 24pt;
    }
    .sudo_highlight_td {
        background-color: yellow;
    }

    .sudo_concluded_td {
        font-size: 16pt;
        font-family: "lucida handwriting","comic sans ms",sans-serif;
        color: #7777DD;
    }

</style>
